﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Net.Sockets;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using Newtonsoft.Json;
using BaseSimpleAPI;
using BaseDao;

namespace UDPHelper
{
    public class UDPServer : IBaseServer
    {
        public UDPServer()
        {
            _UDPManager = new UDPManager();
            _UDPManager.AddReceiveCallback(ReceiveCallback);

            _UDPManager.UDPPackageManager = UDPPackageQueueHelper.GetInstance();

            Port = int.Parse(ConfigurationManager.AppSettings["SystemData::Port"] ?? "0");
        }

        /// <summary>
        /// 接收到消息的回调
        /// </summary>
        /// <param name="package"></param>
        private void ReceiveCallback(UDPPackage package)
        {
            var call_centxt = NetCallContext.NewCurrent();

            var action_name = UDPPackageHelper.GetHeader(package, "Action");
            var pipeline = RouteData.FindValue(action_name);

            StringBuilder sb = new StringBuilder();

            if (pipeline == null)
            {
                sb.Append(JsonConvert.SerializeObject(StatusData.Error("Not find Pipeline in RoutData")));
            }
            else if (!pipeline.Handle(package))
            {
                sb.Append(JsonConvert.SerializeObject(StatusData.Error("Pipeline Handle Error")));
            }

            // 存在数据
            if (sb.Length > 0)
            {
                var rpackage = new UDPPackage
                {
                    Header = package.Header,
                    Body = sb.ToString(),
                    IPAddress = package.IPAddress,
                    Port = package.Port,
                };
                _UDPManager.UDPPackageManager.PushUDPPackageToStack(rpackage);
            }
        }

        private UDPManager _UDPManager = null;

        /// <summary>
        /// 使用的端口号
        /// </summary>
        public int Port { get { return _UDPManager.Port; } set { _UDPManager.Port = value; } }

        /// <summary>
        /// 简单路由
        /// （链接处理到具体的管道上，然后将数据交给管道处理）
        /// </summary>
        public RouteData<Pipeline> RouteData = new RouteData<Pipeline>();

        public void Start()
        {
            _UDPManager.Start();
        }

        /// <summary>
        /// 加载全部的Controller
        /// </summary>
        public void LoadAllController()
        {
            List<Type> types = new List<Type>();

            var start_dir = Directory.GetCurrentDirectory();
            var files = Directory.GetFiles(start_dir);

            var item_file_extension = ".dll;".Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var item in files)
            {
                if (item_file_extension.Contains(Path.GetExtension(item).ToLower()))
                    types.AddRange(TypeHelper.SearchType<BaseController>(Path.GetFileNameWithoutExtension(item)));
            }

            var ig_controller_names = new[] { "BaseController", "BaseController`3" };

            foreach (var controller_type in types)
            {
                if (ig_controller_names.Contains(controller_type.Name))
                    continue;

                BaseController controller = TypeHelper.CreateInstance<BaseController>(controller_type);

                foreach (var action_method in controller.GetType().GetMethods())
                {
                    var route_keys = RouteData.GetFormatKeys(new Dictionary<string, string> {
                        { "Controller", controller.GetType().Name },
                        { "Action", action_method.Name },
                    });

                    foreach (var route_key in route_keys)
                    {
                        RouteData.Register(route_key, new UDPActionPipeline { Controller = controller, Method = action_method });
                    }
                }
            }
        }

        /// <summary>
        /// 停止运行
        /// </summary>
        public void Stop()
        {
            _UDPManager.Stop();
        }

        /// <summary>
        /// 是否正在运行
        /// </summary>
        public bool IsRuning
        {
            get { return _UDPManager.IsRuning; }
        }
    }
}
